#include <iostream>
#include <memory>

//Product interface
class Product{
public:
    virtual ~Product() = default;
    virtual std::string Operation() const = 0;
};

//Concrete productA
class ConcreteProductA : public Product{
public:
    std::string Operation() const override{
        return "Result of ConcreeProductA";
    }
};

//Concrete productB
class ConcreteProductB : public Product{
public:
    std::string Operation() const override{
        return "Result of ConcreeProductB";
    }
};

//Concrete productC
class ConcreteProductC : public Product{
public:
    std::string Operation() const override{
        return "Result of ConcreeProductC";
    }
};

//Simple factory
class SimpleFactory{
public:
    std::unique_ptr<Product> CreateProduct(const std::string& type) const{
        if (type == "A")
        {
            return std::make_unique<ConcreteProductA>();
        }
        else if (type == "B")
        {
            return std::make_unique<ConcreteProductB>();
        }
        else if (type == "C")
        {
            return std::make_unique<ConcreteProductC>();
        }

        return nullptr;
    }
};

//Client
void ClientCode(const SimpleFactory& factory)
{
    std::cout << "Client: Creating product A\n";
    auto productA = factory.CreateProduct("A");
    if (productA)
    {
        std::cout << productA->Operation() << std::endl;
    }

    std::cout << "Client: Creating product B\n";
    auto productB = factory.CreateProduct("B");
    if (productA)
    {
        std::cout << productA->Operation() << std::endl;
    }

    std::cout << "Client: Creating product C\n";
    auto productC = factory.CreateProduct("C");
    if (productA)
    {
        std::cout << productA->Operation() << std::endl;
    }
}

int main()
{
    SimpleFactory factory;
    ClientCode(factory);
    return 0;
}